//============================================================================
// Copyright (C) 2009-2013 Brett R. Jones 
// All Rights Reserved
//
// You may redistribute and/or modify for non commercial and commercial uses 
// provided this copyright notice remains in place and is not modified
//
// This code is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// brettjones1900@gmail.com
// http://www.p2panarchy.com
//============================================================================

#include "RcSktLib.h"

// implements a manager to manage connect sockets
//============================================================================
//=== constructor ===//
RcSktConnectMgr::RcSktConnectMgr()
{
	m_eSktMgrType = eSktMgrTypeTcpConnect;
}

//============================================================================
//=== destructor ===//
RcSktConnectMgr::~RcSktConnectMgr()
{
	if( m_aoSktsToDelete.size()  )
	{
		int iCnt = (int)m_aoSktsToDelete.size();
		for( int i = 0; i < iCnt; i++ )
		{
			delete m_aoSktsToDelete[i];
		}
	}
}

//============================================================================
//! make a new socket... give derived classes a chance to override
VxSktBase * RcSktConnectMgr::makeNewSkt( void )
{ 
	return new RcSktConnect(); 
}

//============================================================================
//! Connect to ip or url and return socket.. if cannot connect return NULL
RcSktConnect * RcSktConnectMgr::ConnectTo(	const char *	pIpOrUrl,				// remote ip or url 
											U16				u16Port,				// port to connect to
											int				iTimeoutMilliSeconds )	// milli seconds before connect attempt times out
{
#ifdef DEBUG_SKTS
	log_msg( LOG_SKT, "RcSktConnectMgr::ConnectTo: start\n" );
#endif // DEBUG_SKTS
	if( NULL ==  m_pfnUserRecieve )
	{
		log_msg( LOG_SKT, "RcSktConnectMgr::ConnectTo: you must call SetRecieveCallback first\n" );
		vx_assert( m_pfnUserRecieve );
	}
	//VxVerifyCodePtr( m_pfnUserRecieve );

	RcSktConnect * poSkt	= (RcSktConnect *)makeNewSkt();
	poSkt->m_poSktMgr		= this;
	//VxVerifyCodePtr( m_pfnOurRecieve );
	poSkt->m_pfnRecieve		= m_pfnOurRecieve;
	poSkt->m_pfnTransmit	= m_pfnOurTransmit;
	RCODE rc = poSkt->ConnectTo(	m_oLclIp,
									pIpOrUrl, 
									u16Port, 
									iTimeoutMilliSeconds );

	if( rc )
	{
#ifdef DEBUG_SKTS
		log_msg( LOG_SKT, "RcSktConnectMgr::ConnectTo: error %d\n", rc );
#endif // DEBUG_SKTS

		delete poSkt;
		return NULL;
	}
#ifdef DEBUG_SKTS
	log_msg( LOG_SKT, "RcSktConnectMgr::ConnectTo: adding skt\n", poSkt->m_iSktId );
#endif // DEBUG_SKTS
	AddSkt( poSkt );
	//log_msg( LOG_SKT, "RcSktConnectMgr::ConnectTo: done\n" );

	return poSkt;
}

//============================================================================
//! handle received data 
void RcSktConnectMgr::HandleRecieveData( RcSktBase * poSkt )
{
}

/*
//============================================================================
//! delete a socket.. allow derived classes to handle differently if they want to
void RcSktConnectMgr::DeleteSkt( VxSktBase * poSkt )	// skt to remove
{
	if( m_aoSktsToDelete.size() >= 50 )
	{
		delete m_aoSktsToDelete[0];
		m_aoSktsToDelete.erase( m_aoSktsToDelete.begin() );
	}
	m_aoSktsToDelete.push_back( poSkt );
}
*/